package org.example.shop_front_api.controller;

import org.example.shop_front_api.entity.ESInformation;
import org.example.shop_front_api.utils.JsonResult;
import org.example.shop_front_api.utils.Tool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.client.elc.NativeQueryBuilder;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.HighlightQuery;
import org.springframework.data.elasticsearch.core.query.highlight.Highlight;
import org.springframework.data.elasticsearch.core.query.highlight.HighlightField;
import org.springframework.data.elasticsearch.core.query.highlight.HighlightParameters;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("api/information")
public class EsInformationController {
    @Autowired
    private ElasticsearchOperations elasticsearchOperations;

    // 创建索引
    @GetMapping("create")
    public JsonResult create() {
        IndexOperations indexOperations = elasticsearchOperations.indexOps(ESInformation.class);
        if (!indexOperations.exists()) {
            indexOperations.create();
        }
        return JsonResult.success("ok", null);
    }

    // 索引文档
    @PostMapping("add")
    public JsonResult add(@RequestBody ESInformation information) {
        information.setCreateTime(Tool.getCurrentTime());
        System.out.println(information);
        ESInformation result = elasticsearchOperations.save(information);
        return JsonResult.success("添加成功", information);
    }

    // 根据id查询文档
    @GetMapping("getById")
    public JsonResult getById(@RequestParam("id") String id) {
        if (id.isEmpty()) {
            return JsonResult.failed("id不能为空");
        }
        ESInformation info = elasticsearchOperations.get(id, ESInformation.class);
        if (info == null) {
            return JsonResult.failed("文档不存在");
        }
        return JsonResult.success("查询成功", info);
    }

    // 删除文档（文档不存在时提示）
    @GetMapping("delete")
    public JsonResult delete(@RequestParam("id") String id) {
        if (id.isEmpty()) {
            return JsonResult.failed("id不能为空");
        }
        ESInformation info = elasticsearchOperations.get(id, ESInformation.class);
        if (info == null) {
            return JsonResult.failed("文档不存在，无法删除");
        }
        String result = elasticsearchOperations.delete(id, ESInformation.class);
        return JsonResult.success("删除成功", null);
    }

    // 搜索接口
    @GetMapping("search")
    public JsonResult search(@RequestParam(value = "wd", required = false) String wd) {
        // 高亮
        HighlightField highlightField = new HighlightField("title");
        HighlightParameters parameters = HighlightParameters.builder()
                .withPreTags("<span style='color: red'>")
                .withPostTags("</span>")
                .withFragmentSize(Integer.MAX_VALUE)
                .withNumberOfFragments(1)
                .build();
        Highlight highlight = new Highlight(parameters, List.of(highlightField));
        HighlightQuery highlightQuery = new HighlightQuery(highlight, ESInformation.class);

        // 排序：按创建时间从新到旧
        Sort sort = Sort.by(Sort.Order.desc("create_time"));
        PageRequest pageRequest = PageRequest.of(0, 20, sort);

        // 构建查询
        NativeQuery query;
        if (wd == null || wd.isEmpty()) {
            // 关键字不存在，查询全部数据
            query = NativeQuery.builder()
                    .withQuery(q -> q.matchAll(m -> m))
                    .withPageable(pageRequest)
                    .withHighlightQuery(highlightQuery)
                    .build();
        } else {
            // 关键字存在
            query = NativeQuery.builder()
                    .withQuery(q -> q.multiMatch(m -> m
                            .query(wd)
                            .fields("title^3", "content")
                    ))
                    .withPageable(pageRequest)
                    .withHighlightQuery(highlightQuery)
                    .build();
        }

        // 执行查询
        SearchHits<ESInformation> searchHits = elasticsearchOperations.search(query, ESInformation.class);


        List<HashMap<String, Object>> resultList = searchHits.stream().map(hit -> {
            HashMap<String, Object> data = new HashMap<>();
            data.put("information", hit.getContent());
            if (hit.getHighlightFields().containsKey("title")) {
                data.put("highlightTitle", hit.getHighlightFields().get("title").get(0));
            } else {
                data.put("highlightTitle", hit.getContent().getTitle());
            }
            return data;
        }).collect(Collectors.toList());

        HashMap<String, Object> resultData = new HashMap<>();
        resultData.put("list", resultList);
        resultData.put("totalHits", searchHits.getTotalHits());
        return JsonResult.success("搜索成功", resultData);
    }

    // ik分词搜索接口
    @GetMapping("match")
    public JsonResult match(@RequestParam("wd") String wd) {
        // 排序：按创建时间从新到旧
        Sort sort = Sort.by(Sort.Order.desc("create_time"));
        PageRequest pageRequest = PageRequest.of(0, 10, sort);

        NativeQuery query = NativeQuery.builder()
                .withQuery(q -> q
                        .match(m -> m
                                .field("title")
                                .query(wd)
                        )
                )
                .withPageable(pageRequest)
                .build();

        SearchHits<ESInformation> searchHits = elasticsearchOperations.search(query, ESInformation.class);
        HashMap<String, Object> resultData = new HashMap<>();
        resultData.put("hits", searchHits.getSearchHits());
        resultData.put("totalHits", searchHits.getTotalHits());
        return JsonResult.success("搜索成功", resultData);
    }

    // 高亮搜索
    @GetMapping("highlight")
    public JsonResult highlight(@RequestParam("wd") String wd) {
        // 高亮
        HighlightField highlightField = new HighlightField("title");
        HighlightParameters parameters = HighlightParameters.builder()
                .withPreTags("<span style='color: red'>")
                .withPostTags("</span>")
                .withFragmentSize(Integer.MAX_VALUE)
                .withNumberOfFragments(1)
                .build();
        Highlight highlight = new Highlight(parameters, List.of(highlightField));
        HighlightQuery highlightQuery = new HighlightQuery(highlight, ESInformation.class);

        // 排序：按创建时间从新到旧
        Sort sort = Sort.by(Sort.Order.desc("create_time"));
        PageRequest pageRequest = PageRequest.of(0, 10, sort);

        // 查询
        NativeQuery query = NativeQuery.builder()
                .withQuery(q -> q
                        .match(m -> m
                                .field("title")
                                .query(wd)
                        )
                )
                .withPageable(pageRequest)
                .withHighlightQuery(highlightQuery)
                .build();

        SearchHits<ESInformation> searchHits = elasticsearchOperations.search(query, ESInformation.class);
        HashMap<String, Object> resultData = new HashMap<>();
        resultData.put("hits", searchHits.getSearchHits());
        resultData.put("totalHits", searchHits.getTotalHits());
        return JsonResult.success("搜索成功", resultData);
    }

    // 多字段匹配
    @GetMapping("muli_match")
    public JsonResult muliMatch(@RequestParam("wd") String wd) {
        // 排序：按创建时间从新到旧
        Sort sort = Sort.by(Sort.Order.desc("create_time"));
        PageRequest pageRequest = PageRequest.of(0, 10, sort);

        // 多字段匹配 查询
        NativeQuery query = new NativeQueryBuilder()
                .withQuery(q -> q.multiMatch(m -> m
                        .query(wd)
                        .fields("title^3", "content")
                ))
                .withPageable(pageRequest)
                .build();

        SearchHits<ESInformation> hits = elasticsearchOperations.search(query, ESInformation.class);
        List<ESInformation> result = hits.stream()
                .map(SearchHit::getContent)
                .collect(Collectors.toList());
        return JsonResult.success("ok", result);
    }
}